package br.ufrn.sipac.patrimonio.coletor.transmissao;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Vector;
import java.util.concurrent.ExecutionException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.content.Context;
import android.os.AsyncTask;
import br.ufrn.sipac.patrimonio.coletor.dominio.Bem;
import br.ufrn.sipac.patrimonio.coletor.dominio.FinalidadeLevantamento;
import br.ufrn.sipac.patrimonio.coletor.dominio.Levantamento;
import br.ufrn.sipac.patrimonio.coletor.dominio.Localidade;
import br.ufrn.sipac.patrimonio.coletor.dominio.Unidade;
import br.ufrn.sipac.patrimonio.coletor.dominio.UsuarioColetor;
import br.ufrn.sipac.patrimonio.coletor.exception.TransmissaoException;

/**
 * Classe centralizadora de requisi��es ao server.
 * 
 * @author Alex
 */
public class GenericSOAP {

	/*
	 * Atributo que armazena a URL para conex�o com servidor.
	 */
	private String URL = "http://cooperacao.info.ufrn.br/sipac/services/services";

	/**
	 * Objeto que encapsula par�metros para o webservice
	 */
	private SoapObject soapObject = null;

	/**
	 * Classe respons�vel pela camada de transporte.
	 */
	HttpTransportSE ht = new HttpTransportSE(URL);

	/**
	 * Envelope respons�vel por encapsular informa��es da resposta.
	 */
	SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
			SoapEnvelope.VER11);

	public GenericSOAP() {
		System.out.println("primeira linha construtor");

		ht.setXmlVersionTag("<?xml version=\"1.0\" encoding= \"UTF-8\" ?>");

	}

	/**
	 * M�todo respons�vel por trazer a lista de finalidades de levantamento
	 * cadastrado no sistema. Fazendo uma requisi��o ao m�todo : getTiposLev()
	 * situado no projeto SIPAC, na classe:
	 * br.ufrn.sipac.patrimonio.operacoes.webservice.OperacoesColetorWSImpl.
	 * 
	 * @return
	 * @throws ExecutionException
	 * @throws Exception
	 * @throws SQLException
	 */
	public Collection findFinalidadesLevantamentoSOAP(Context context)
			throws TransmissaoException {
		Collection finalidades = new ArrayList();
		envelope.dotNet = true;
		soapObject = new SoapObject(URL, "getTiposLev");
		envelope.setOutputSoapObject(soapObject);
		try {
			// Faz a conexão com o webservice.
			AsyncTask<Object, Void, Object> obj = new TrasmissaoTask().execute(
					URL, ht, envelope);
			SoapObject resultado = (SoapObject) obj.get();
			int contador = resultado.getPropertyCount();
			// GenericDAO gen = new GenericDAO();
			for (int i = 0; i < contador; i++) {

				SoapObject objetoFinalidade = (SoapObject) resultado
						.getProperty(i);

				FinalidadeLevantamento finalidade = new FinalidadeLevantamento();

				for (int contadorLoc = 0; contadorLoc < objetoFinalidade
						.getPropertyCount(); contadorLoc++) {

					finalidade.setId(Integer.parseInt(objetoFinalidade
							.getProperty(2).toString()));

					finalidade.setDenominacao(objetoFinalidade.getProperty(3)
							.toString());
				}

				finalidades.add(finalidade);
				// gen.save(finalidade);
			}
		} catch (Exception e) {
			throw new TransmissaoException(context);
		}

		return finalidades;
	}

	/**
	 * Metodo responsavel por fazer a requisicao ao server para trazer as
	 * unidades com base na permissao do usuario. O metodo que e chamado se
	 * encontra no projeto do SIPAC situado na classe :
	 * br.ufrn.sipac.patrimonio.operacoes.webservice.OperacoesColetorWSImpl,
	 * metodo: getUnidadesPermissao(String login).
	 * 
	 * @param login
	 * @return
	 */
	public Collection findUnidadesPermissao(String login, Context context)
			throws TransmissaoException {
		Collection unidades = new ArrayList();
		soapObject = new SoapObject(URL, "getUnidadesPermissao");
		soapObject.addProperty("login", login);
		envelope.setOutputSoapObject(soapObject);
		try {
			// Faz a conexão com o webservice.
			AsyncTask<Object, Void, Object> obj = new TrasmissaoTask().execute(
					URL, ht, envelope);

			SoapObject resultado = (SoapObject) obj.get();
			int contador = resultado.getPropertyCount();

			for (int i = 0; i < contador; i++) {

				SoapObject objetoUnidade = (SoapObject) resultado
						.getProperty(i);

				Unidade uni = new Unidade();

				for (int contadorUni = 0; contadorUni < objetoUnidade
						.getPropertyCount(); contadorUni++) {

					uni.setCodigoUnidade(Long.parseLong(objetoUnidade
							.getProperty(0).toString()));
					Object sigla = objetoUnidade.getProperty(4);
					if (sigla != null) {

						uni.setSigla(sigla.toString());
					}

					uni.setId(Integer.parseInt(objetoUnidade.getProperty(3)
							.toString()));
				}
				if (uni.getSigla() != null && uni.getId() > 0
						&& uni.getCodigoUnidade() > 0) {
					unidades.add(uni);
				}

			}
		} catch (Exception e) {
			new TransmissaoException(context);
		}
		return unidades;
	}

	public Bem findByNumCod(Integer numCod, Context context)
			throws TransmissaoException {

		soapObject = new SoapObject(URL, "getBemByCodBarra");
		soapObject.addProperty("codBarra", numCod);
		envelope.setOutputSoapObject(soapObject);

		try {
			AsyncTask<Object, Void, Object> obj = new TrasmissaoTask().execute(
					URL, ht, envelope);

			SoapObject resultado = (SoapObject) obj.get();

			if (resultado != null) {

				int contador = resultado.getPropertyCount();
				Bem bem = new Bem();
				for (int i = 0; i < contador; i++) {

					SoapObject objetoBem = (SoapObject) resultado
							.getProperty(i);

					if (objetoBem != null) {

						for (int contadorBem = 0; contadorBem < objetoBem
								.getPropertyCount(); contadorBem++) {

							bem.setDenominacao(objetoBem.getProperty(0)
									.toString());
							bem.setId(Integer.parseInt(objetoBem.getProperty(1)
									.toString()));
							Object local = objetoBem.getProperty(2);
							if (local != null) {
								bem.setLocal(new Localidade(Integer
										.parseInt(local.toString())));
							}

							bem.setNumTombamento(Integer.parseInt(objetoBem
									.getProperty(4).toString()));
							bem.setStatus(Integer.parseInt(objetoBem
									.getProperty(5).toString()));
							bem.setUnidade(new Unidade(Integer
									.parseInt(objetoBem.getProperty(3)
											.toString())));

						}

					}

				}

				return bem;

			}
			return null;
		} catch (Exception e) {
			throw new TransmissaoException(context);
		}

	}

	/**
	 * M�todo respons�vel por fazer uma requisi��o de grava��o de levantamento
	 * patrimonial. O m�todo se chama gravarItens(Vector itens, Integer
	 * idUsuario, Integer idTipo, String descricao, Integer idLocal, String
	 * data) situado no projeto SIPAC, na classe:
	 * br.ufrn.sipac.patrimonio.operacoes.webservice.OperacoesColetorWSImpl.
	 * 
	 * @param lev
	 * @param v
	 * @return
	 * @throws ExecutionException
	 * @throws Exception
	 */
	public String gravarLevantamento(Levantamento lev, Vector v, Context context)
			throws TransmissaoException {
		soapObject = new SoapObject(URL, "gravarItens");

		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		soapObject.addProperty("col", v);
		soapObject.addProperty("idUsuario", new Integer(lev.getUsuario()
				.getId()));
		soapObject.addProperty("idTipo", new Integer(lev.getTipo().getId()));
		soapObject.addProperty("descricao", lev.getDescricao());
		soapObject.addProperty("idLocal", new Integer(lev.getLocal().getId()));
		soapObject.addProperty("data", sdf.format(lev.getDataCadastro()));

		envelope.setOutputSoapObject(soapObject);

		try {
			AsyncTask<Object, Void, Object> obj = new TrasmissaoTask().execute(
					URL, ht, envelope);
			Object resultado = obj.get();
			return resultado.toString();
		} catch (Exception e) {
			throw new TransmissaoException(context);
		}

	}

	/**
	 * M�todo que traz a lista de localidades com base no usu�rio logado,
	 * realiza uma requisi��o ao server, ao m�todo getLocalidades(Integer
	 * idUnidade), situado na classe:
	 * br.ufrn.sipac.patrimonio.operacoes.webservice.OperacoesColetorWSImpl
	 * 
	 * @param login
	 * @return
	 */
	public Collection findLocaisByUnidade(int idUnidade, long codigoUnidade,
			Context context) throws TransmissaoException {

		soapObject = new SoapObject(URL, "getLocalidades");
		soapObject.addProperty("idUnidade", Integer.valueOf(idUnidade));
		soapObject.addProperty("codigoUnidade", Long.valueOf(codigoUnidade));
		envelope.setOutputSoapObject(soapObject);

		try {
			// Faz a conexão com o webservice.
			AsyncTask<Object, Void, Object> obj = new TrasmissaoTask().execute(
					URL, ht, envelope);

			Collection localidades = new ArrayList();

			SoapObject resultado = (SoapObject) obj.get();
			int contador = resultado.getPropertyCount();

			for (int i = 0; i < contador; i++) {

				SoapObject objetoLocalidade = (SoapObject) resultado
						.getProperty(i);
				Localidade loc = new Localidade();

				for (int contadorLoc = 0; contadorLoc < objetoLocalidade
						.getPropertyCount(); contadorLoc++) {

					if (objetoLocalidade.getProperty(0) == null) {

					} else {
						loc.setCodigo(objetoLocalidade.getProperty(0)
								.toString());
					}

					loc.setUnidade(new Unidade(idUnidade));
					loc.setId(Integer.parseInt(objetoLocalidade.getProperty(2)
							.toString()));

				}

				localidades.add(loc);

			}

			return localidades;
		} catch (Exception e) {
			throw new TransmissaoException(context);
		}

	}

	/**
	 * M�todo que realiza a autentica��o com base na entidade do projeto SIPAC:
	 * patrimonio.usuario_coletor, tal entidade � populada no sistema SIPAC, no
	 * caminho Patrim�nio -> Cadastros -> Usu�rio Coletor e � representada no
	 * endere�o projeto:
	 * 
	 * @param login
	 * @param senha
	 */
	public Boolean autenticar(String login, String senha, Context context)
			throws TransmissaoException {
		Boolean autenticado = false;

		/**
		 * Chamando m�todo do WSDL.
		 */
		soapObject = new SoapObject(URL, "confirmarSenha");

		/**
		 * Enviando par�metros para autentica��o.
		 */
		soapObject.addProperty("login", login);
		soapObject.addProperty("senha", senha);

		/**
		 * Envelopando o objeto com par�metros para serem posteriormente
		 * transportados.
		 */
		envelope.setOutputSoapObject(soapObject);
		try {
			// Faz a conexão com o webservice.
			AsyncTask<Object, Void, Object> obj = new TrasmissaoTask().execute(
					URL, ht, envelope);

			/**
			 * Capturando resposta do server.
			 */
			Object resultado = (Object) obj.get();

			autenticado = Boolean.valueOf(resultado.toString());

		} catch (Exception ex) {
			throw new TransmissaoException(context);
		}

		return autenticado;

	}

	/**
	 * Metodo responsavel por realizar uma requisicao ao server para capturar
	 * informacoes sobre o usuario que esta no coletor. O metodo do server se
	 * chama: getUsuario(String login), situado na classe:
	 * br.ufrn.sipac.patrimonio.operacoes.webservice.OperacoesColetorWSImpl.
	 * 
	 * @param login
	 * @return
	 */
	public UsuarioColetor capturarUsuario(String login, Context context)
			throws TransmissaoException {

		soapObject = new SoapObject(URL, "getUsuario");
		soapObject.addProperty("login", login);

		envelope.setOutputSoapObject(soapObject);
		try {
			// Faz a conexão com o webservice.
			AsyncTask<Object, Void, Object> obj = new TrasmissaoTask().execute(
					URL, ht, envelope);

			SoapObject resultado = (SoapObject) obj.get();

			SoapObject objetoUsuario = (SoapObject) resultado.getProperty(0);

			UsuarioColetor usu = new UsuarioColetor();
			usu.setId(Integer.parseInt(objetoUsuario.getProperty("id")
					.toString()));

			usu.setUnidade(new Unidade(Integer.parseInt(objetoUsuario
					.getProperty("idUnidade").toString())));
			usu.setLogin(objetoUsuario.getProperty("login").toString());

			return usu;
		} catch (Exception e) {
			throw new TransmissaoException(context);
		}
	}

}
